package com.example.websocketserver.configuration;

import com.example.websocketserver.RuntimeTest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.SubscribableChannel;
import org.springframework.util.CollectionUtils;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.messaging.SubProtocolWebSocketHandler;

import java.security.Principal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 重写websocket-stomp处理器
 *
 * @author liulei
 * @version 1.0
 */
@Slf4j
public class MySubProtocolWebSocketHandler extends SubProtocolWebSocketHandler implements CommandLineRunner {

    private static String USER_COUNT_KEY = "com:ecej:iot:homehub:ws:conn:";

    /**
     * 【自定义】存储所有用户的连接
     */
    public static Map<String, List<String>> sessionCreates = new ConcurrentHashMap<>(16);

    private final MessageChannel clientInboundChannel;
    private final SubscribableChannel clientOutboundChannel;

    /**
     * Create a new {@code MySubProtocolWebSocketHandler} for the given inbound and outbound channels.
     *
     * @param clientInboundChannel  the inbound {@code MessageChannel}
     * @param clientOutboundChannel the outbound {@code MessageChannel}
     */
    public MySubProtocolWebSocketHandler(MessageChannel clientInboundChannel, SubscribableChannel clientOutboundChannel) {
        super(clientInboundChannel, clientOutboundChannel);
        this.clientInboundChannel = clientInboundChannel;
        this.clientOutboundChannel = clientOutboundChannel;
    }

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        super.afterConnectionEstablished(session);
        // 当前用户的连接数+1
        Principal principal = session.getPrincipal();
        if (null != principal) {
            List<String> userSessions = sessionCreates.get(principal.getName());
            if (userSessions == null) {
                userSessions = new ArrayList<>();
            }
            if (!userSessions.contains(principal.getName())) {
                userSessions.add(session.getId());
                sessionCreates.put(principal.getName(), userSessions);
            }
        }
        String redisKey = USER_COUNT_KEY + principal.getName();
        log.info("websocket->自定义记录session创建记录：{}|{}", principal.getName(), session.getId());
        printMemory();
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
        super.afterConnectionClosed(session, closeStatus);
        // 当前用户的连接数-1
        Principal principal = session.getPrincipal();
        if (null != principal) {
            List<String> userSessions = sessionCreates.get(principal.getName());
            if (!CollectionUtils.isEmpty(userSessions) && !userSessions.contains(principal.getName())) {
                userSessions.remove(session.getId());
            }
        }
        String redisKey = USER_COUNT_KEY + session.getPrincipal().getName();
        log.info("websocket->自定义记录session销毁记录：{}|{}|{}", session.getPrincipal().getName(), session.getId());
        printMemory();
    }

    @Override
    public String toString() {
        return "MySubProtocolWebSocketHandler" + getDefaultProtocolHandler();
    }

    @Override
    public void run(String... args) throws Exception {
        // TODO 清除分布式计数器
    }

    /**
     * 打印内存信息
     */
    private void printMemory() {
        try {
            RuntimeTest.property();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
